﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class QTEGame : MonoBehaviour {

    public KeyPanel LeftKeyPanel;
    public KeyPanel RightKeyPanel;
    public Process Process;

    private Action<bool> onResult;
    private bool QTEGameRunning = false;
    private QTEChecker leftChecker;
    private QTEChecker rightChecker;

    public void Start()
    {
        leftChecker = new QTEChecker(LeftKeyPanel);
        rightChecker = new QTEChecker(RightKeyPanel);
        LeftKeyPanel.gameObject.SetActive(false);
        RightKeyPanel.gameObject.SetActive(false);
    }

    public void OnGUI()
    {
        Event e = Event.current;
        if (QTEGameRunning)
        {
            if (e.isKey)
            {
                if (Input.anyKeyDown)
                {
                    Debug.Log("key down " + e.keyCode);

                    switch (e.keyCode)
                    {
                        case KeyCode.W:
                        case KeyCode.A:
                        case KeyCode.S:
                        case KeyCode.D:
                            if (!leftChecker.Check(e.keyCode))
                            {
                                qteFail();
                            }
                            break;
                        case KeyCode.UpArrow:
                        case KeyCode.LeftArrow:
                        case KeyCode.DownArrow:
                        case KeyCode.RightArrow:
                            if (!rightChecker.Check(e.keyCode))
                            {
                                qteFail();
                            }
                            break;
                        case KeyCode.None:
                            break;
                        default:
                            if (!leftChecker.Complete() || !rightChecker.Complete())
                                qteFail();
                            else
                            {
                                qteSuccess();
                            }
                            break;
                    }
                }
            }

            if (leftChecker.Complete() && rightChecker.Complete())
                qteSuccess();
        }
    }

    public void StartGame(QTEContent qTEContent , Action<bool> onResult)
    {
        QTEGameRunning = true;
        this.onResult = onResult;
        leftChecker.NewSequence(qTEContent.LeftQTEKeys);
        rightChecker.NewSequence(qTEContent.RightQTEKeys);
        LeftKeyPanel.ShowKeys(qTEContent.LeftQTEKeys);
        RightKeyPanel.ShowKeys(qTEContent.RightQTEKeys);
        StartCoroutine(timeCount(qTEContent.TimeLimit));
        LeftKeyPanel.gameObject.SetActive(true);
        RightKeyPanel.gameObject.SetActive(true);
    }

    private void clearKey()
    {
        LeftKeyPanel.ShowKeys();
        RightKeyPanel.ShowKeys();
        LeftKeyPanel.gameObject.SetActive(false);
        RightKeyPanel.gameObject.SetActive(false);
        Process.End();
    }

    private void qteSuccess()
    {
        clearKey();
        QTEGameRunning = false;
        onResult(true);
    }
    
    private void qteFail()
    {
        clearKey();
        QTEGameRunning = false;
        onResult(false);
    }

    private IEnumerator timeCount(float time)
    {
        Process.gameObject.SetActive(true);
        Process.StartProcess(time);
        yield return new WaitForSeconds(time);
        if (QTEGameRunning)
            qteFail();
    }
}

public class QTEChecker
{
    private KeyPanel keyPanel;
    private List<QTEKey> qTEKeys = new List<QTEKey>();
    private int currentIndex = 0;

    public QTEChecker(KeyPanel keyPanel)
    {
        this.keyPanel = keyPanel;
    }

    public bool Complete()
    {
        return currentIndex >= qTEKeys.Count;
    }

    public bool Check(KeyCode keyCode)
    {
        if (!Complete())
        {
            Debug.Log("target key is " + qTEKeys[currentIndex].KeyCode);
            if (qTEKeys[currentIndex].KeyCode == keyCode)
            {
                keyPanel.ShowPressed(currentIndex);
                moveNext();
                return true;
            }
            else
                return false;
            
        }
        return true;
    }

    public void NewSequence(List<QTEKey> qTEKeys)
    {
        currentIndex = 0;
        this.qTEKeys = qTEKeys;

    }

    private void moveNext()
    {
        currentIndex++;
    }
}
